#include "Shader.h"
#include <iostream>
#include <fstream>
#include "debug.h"

Shader::Shader(std::string name, SHADERTYPE::ST type){
	m_name = name;
	m_shaderType = type;
	m_debugState = true;
	m_compiled = false;

	switch(type)
	{
		case SHADERTYPE::VERTEX :  { m_shaderHandle = glCreateShader(GL_VERTEX_SHADER); break;} 
		case SHADERTYPE::FRAGMENT:  { m_shaderHandle = glCreateShader(GL_FRAGMENT_SHADER); break;} 
		case SHADERTYPE::GEOMETRY:  { m_shaderHandle = glCreateShader(GL_GEOMETRY_SHADER); break;} 
		case SHADERTYPE::TESSELLATION:  { m_shaderHandle = NULL; std::cerr << "no tesselation bitch!"; } 
	}
	m_refCount = 0;
	m_source = 0;
}

Shader::~Shader() {}

void Shader::compile() {
	if (m_source == 0)
	{
		std::cerr<<"Warning no shader source loaded\n";
		return;
	}
	glCompileShader(m_shaderHandle);
	if(m_debugState==true)
	{
		std::cerr <<"Compiling Shader "<<m_name<<"\n";
		printInfoLog(m_shaderHandle);
	}
	m_compiled=true;
}

void Shader::load(std::string name) { 
	if(m_source != 0)
	{
		std::cerr << "deleting existing source code \n";
		delete m_source;
	}

	std::ifstream shaderSource(name.c_str());
	if (!shaderSource.is_open())
	{
		std::cerr<<"File not found "<<name.c_str()<<"\n";
		exit(EXIT_FAILURE);
	}
	// now read in the data
	m_source = new std::string((std::istreambuf_iterator<char>(shaderSource)), std::istreambuf_iterator<char>());
	shaderSource.close();
	*m_source+="\0";
 
	const char* data=m_source->c_str();
	glShaderSource(m_shaderHandle , 1, &data,NULL);
	m_compiled=false;
 
	if (m_debugState == true)
	{
		std::cerr<<"Shader Loaded and source attached\n";
		printInfoLog<GLuint>(m_shaderHandle);
	}
}

void Shader::toggleDebug() { m_debugState = !m_debugState; }

GLuint Shader::getShaderHandle() { return m_shaderHandle; }

void Shader::incrementRefCount() { m_refCount++;}

void Shader::decrementRefCount() { m_refCount--;}

int Shader::getRefCount() { return m_refCount;}